package com.ybt.communicate.tcp.dispacher.impl;

import org.apache.log4j.Logger;

import com.ruleengine.context.IContextProperty;
import com.ruleengine.context.IWorkflowConext;
import com.ruleengine.context.impl.ContextPropertyFactory;
import com.ruleengine.context.impl.WorkflowContextFactory;
import com.ruleengine.endpoint.data.IEndpointData;
import com.ruleengine.frame.callback.IRuleEngineCallback;
import com.ruleengine.frame.impl.WorkflowExecuter;
import com.ybt.channel.manager.ChannelManager;
import com.ybt.communicate.core.IConnection;
import com.ybt.communicate.core.exception.ProtocolException;
import com.ybt.communicate.tcp.dispacher.ITCPServerDispatcher;
import com.ybt.context.IYBTContextConstants;

public class TCPServerDispatcherForChannel implements ITCPServerDispatcher {
    private static Logger logger = Logger.getLogger(TCPServerDispatcherForChannel.class);
    public void dispatch(final IConnection connection) throws ProtocolException {
        // TODO Auto-generated method stub
        try {
            // 协议id
            String reqProtocol = connection.getProtocolId();

            // 渠道识别
            String channel = ChannelManager.getInstance()
                    .getChannelByReqProtocol(reqProtocol);
            logger.debug("the request is from "+channel);
            
            // 创建工作流context
            logger.debug("create context for the request...");
            IWorkflowConext newContext = WorkflowContextFactory.getInstance()
                    .createWorkflowContext(channel);

            // 设置识别的渠道
            IContextProperty<String> fromPro = ContextPropertyFactory
                    .getInstance().createPublicConstant(
                            IYBTContextConstants.YBT_CHANNEL);
            fromPro.setValue(channel);
            newContext.setContextProperty(fromPro);

            //接收数据
            Object content = connection.receive();
            // 原始数据
            IContextProperty<Object> dataPro = ContextPropertyFactory
            .getInstance().createPublicVariable(
                    IYBTContextConstants.ORIGINAL_DATA);
            dataPro.setValue(content);
            newContext.setContextProperty(dataPro);
            
            WorkflowExecuter.getInstance().executeNonBlocking(newContext,
                    null, new IRuleEngineCallback() {

                        public void onException(IWorkflowConext context,
                                Exception e) {
                            // TODO Auto-generated method stub
                            logger.error(e,e);
                            try {
                                connection.close();
                            } catch (ProtocolException e1) {
                                // TODO Auto-generated catch block
                                logger.error("close the connection ["+connection.getProtocolId()+"] error",e1);
                            }
                        }

                        public void onComplete(IWorkflowConext context,
                                IEndpointData data) {
                            // TODO Auto-generated method stub
                            try {
                                // 原始数据
                                IContextProperty<Object> dataPro = context.getContextProperty(
                                        IYBTContextConstants.ORIGINAL_DATA);
                                connection.send(context, dataPro.getValue());
                            } catch (ProtocolException e) {
                                // TODO Auto-generated catch block
                                logger.error(e,e);
                            }
                        }

                    });
        } catch (Exception e) {
            // TODO Auto-generated catch block
            throw new ProtocolException(e);
        }
    }

}
